package com.demo;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class Puzzle extends Activity implements OnClickListener {

	private Button btn_restore;
	private Button btn_ruffle;
	private Button btn_demo;
	private Button btn_setting;
	private Button btn_select;
	private ImageView iv_target;
	private TableLayout tl_puzzle;

	protected TimerThread timerThread;
	final static int RES_ID_BASE = 1000;
	protected Bitmap sourcePicture;

	// Random init
	protected int initRuffleLevel = 0;// 300;

	protected JigsawGame game;

	protected int rows = 3;
	protected int cols = 3;
	protected int picWidth = 510;
	protected int picHeight = 510;
	protected int blockWidth = 170;
	protected int blockHeight = 170;

	protected int[] originPicIndex;
	protected int[] picIndex;
	protected List<Integer> resolveSteps;
	protected String lastMoveDirect = "";

	protected Handler timerHandler;
	final static int TIME_COUNT = 1;// ��ʼ��ʱ
	final static int AUTO_PLAY = 2;// �Զ����ƴͼ
	final static int MUSIC_START = 3;// ��������

	protected boolean isGameStart = false;
	protected boolean isAutoPlay = false;
	protected boolean isMusicNeedStart = true;

	protected int ticker;
	protected String strTimeLapsed = "";

	protected int autoIdx = 0;
	private int control_type = 0;
	private int temp_row = 3;
	private int temp_col = 3;
	private int temp_type;
	private List<View> temp_swap = new ArrayList<View>();
	private List<Bitmap> temp_bitmap = new ArrayList<Bitmap>();

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.puzzle);
		findViews();
		initPicBlocks();
		initTimers();
	}

	private void initPicBlocks() {
		tl_puzzle.removeAllViewsInLayout();

		TableRow.LayoutParams lpBlock = new TableRow.LayoutParams(
				TableRow.LayoutParams.WRAP_CONTENT,
				TableRow.LayoutParams.WRAP_CONTENT);

		iv_target.setImageBitmap(sourcePicture);

		for (int i = 0; i < rows; i++) {
			Log.i("puzzle", "row = " + i);
			TableRow curRow = new TableRow(this);
			for (int j = 0; j < cols; j++) {
				Log.i("puzzle", "col = " + j);
				final ImageView curView = new ImageView(this);
				curView.setId(RES_ID_BASE + i * cols + j);
				curView.setLayoutParams(lpBlock);
				Bitmap bitmap = zoomBitmap(sourcePicture, picWidth, picHeight);
				final Bitmap blockBitmap = Bitmap.createBitmap(bitmap, j
						* blockWidth, i * blockHeight, blockWidth, blockHeight);
				curView.setImageBitmap(blockBitmap);

				curView.setOnClickListener(new OnClickListener() {
					public void onClick(View v) {
						if (control_type == 0) {
							// Bitmap b = curView.
							Drawable drawable = curView.getDrawable();
							Bitmap b = ((BitmapDrawable) drawable).getBitmap();
							Bitmap bit = toGrayscale(b);
							curView.setImageBitmap(bit);
							temp_swap.add(v);
							temp_bitmap.add(b);
							if (temp_swap.size() == 2) {
								curView.setImageBitmap(b);
								// temp_swap.get(0)
								ImageView iv = (ImageView) findViewById(temp_swap
										.get(0).getId());
								iv.setImageBitmap(temp_bitmap.get(0));
								Log.e("lei", "--" + temp_swap.get(0).getId()
										+ "  --" + temp_swap.get(1).getId());
								if (temp_swap.get(0).getId() != temp_swap
										.get(1).getId()) {

									swapTwoBlock(temp_swap.get(0), temp_swap
											.get(1));

								}
								temp_swap.clear();
								temp_bitmap.clear();
							}
							// swapTwoBlock(v1, v2)
						} else if (control_type == 1) {
							moveBlockToBlank(v);
						}
					}
				});

				curRow.addView(curView);
			}
			tl_puzzle.addView(curRow);
		}

	}

	private void moveBlockToBlank(View v) {
		if (isGameStart) {
			int curLoc = v.getId() - RES_ID_BASE;
			if (picIndex[curLoc] < rows * cols - 1) {
				int moveRow = getRowIndex(curLoc);
				int moveCol = getColIndex(curLoc);

				int blankLoc = getBlankLocation();
				int blankRow = getRowIndex(blankLoc);
				int blankCol = getColIndex(blankLoc);

				if ((moveCol == blankCol + 1 || moveCol == blankCol - 1)
						&& moveRow == blankRow
						|| (moveRow == blankRow + 1 || moveRow == blankRow - 1)
						&& moveCol == blankCol) {
					swapPicBlockIndex(curLoc, blankLoc);

					showPicBlock(picIndex[blankLoc], blankLoc);
					showPicBlock(picIndex[curLoc], curLoc);

					checkWin();
				}
			}
		}
	}

	private void swapTwoBlock(View v1, View v2) {
		if (isGameStart) {
			int curLoc = v1.getId() - RES_ID_BASE;
			int blankLoc = v2.getId() - RES_ID_BASE;
			int moveRow = getRowIndex(curLoc);
			int moveCol = getColIndex(curLoc);

			int blankRow = getRowIndex(blankLoc);
			int blankCol = getColIndex(blankLoc);
			if (control_type == 0) {
				swapPicBlockIndex(curLoc, blankLoc);

				showPicBlock(picIndex[blankLoc], blankLoc);
				showPicBlock(picIndex[curLoc], curLoc);

				checkWin();
			} else if (control_type == 1) {
				if ((moveCol == blankCol + 1 || moveCol == blankCol - 1)
						&& moveRow == blankRow
						|| (moveRow == blankRow + 1 || moveRow == blankRow - 1)
						&& moveCol == blankCol) {
					swapPicBlockIndex(curLoc, blankLoc);

					showPicBlock(picIndex[blankLoc], blankLoc);
					showPicBlock(picIndex[curLoc], curLoc);

					checkWin();
				}
			}

		}
	}

	private int getBlankLocation() {
		for (int i = 0; i < picIndex.length; i++) {
			if (picIndex[i] == (cols * rows - 1)) {
				return i;
			}
		}

		return -1;
	}

	private void swapPicBlockIndex(int curLoc, int blankLoc) {
		int temp = picIndex[curLoc];
		picIndex[curLoc] = picIndex[blankLoc];
		picIndex[blankLoc] = temp;
	}

	private void checkWin() {
		boolean isWin = true;
		for (int i = 0; i < picIndex.length - 1; i++) {
			if (picIndex[i] != i) {
				isWin = false;
			}
		}

		if (isWin) {
			isGameStart = false;

			showLastPicBlock();

			new AlertDialog.Builder(this).setTitle("Congratulations!")
					.setMessage("You had win this game!").setPositiveButton(
							"OK", new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									dialog.dismiss();
								}
							}).create().show();
		}
	}

	private void showLastPicBlock() {
		ImageView curBlock = (ImageView) findViewById(RES_ID_BASE + rows * cols
				- 1);
		Bitmap bitmap = zoomBitmap(sourcePicture, picWidth, picHeight);
		curBlock.setImageBitmap(Bitmap
				.createBitmap(bitmap, (cols - 1) * blockWidth, (rows - 1)
						* blockHeight, blockWidth, blockHeight));
	}

	private void demoAutoPlay() {
		if (resolveSteps == null || resolveSteps.size() == 0
				|| isGameStart == false) {
			new AlertDialog.Builder(this).setTitle(
					"Sorry,Please run ruffle first!").setPositiveButton("OK",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							/* User clicked OK so do some stuff */
							dialog.dismiss();
						}
					}).create().show();
		} else {
			isGameStart = false;
			isAutoPlay = true;

			picIndex = new int[cols * rows];
			for (int i = 0; i < picIndex.length; i++) {
				picIndex[i] = originPicIndex[i];
			}

			showAllPicBlocks();
			autoIdx = resolveSteps.size() - 1;
		}
	}

	private void autoMoveBlock() {
		int blankLoc = getBlankLocation();

		int curLoc = resolveSteps.get(autoIdx);
		// Log.i("info", "loc:" + curLoc);
		if (initRuffleLevel == 0) {
			curLoc = getPicLocation(curLoc);
			// Log.i("info", "loc:" + curLoc);
		}
		int moveRow = getRowIndex(curLoc);
		int moveCol = getColIndex(curLoc);

		int moveIdx = picIndex[curLoc];
		if (initRuffleLevel == 0) {
			moveIdx = resolveSteps.get(autoIdx);
		}

		// show();

		if (moveIdx != -1) {
			swapPicBlockIndex(moveRow * cols + moveCol, blankLoc);

			showPicBlock(picIndex[blankLoc], blankLoc);
			showPicBlock(picIndex[curLoc], curLoc);
		}

		autoIdx--;

		if (autoIdx < 0) {
			isAutoPlay = false;
			isGameStart = false;

			showLastPicBlock();

		}
	}

	private int getPicLocation(int idx) {
		for (int i = 0; i < picIndex.length; i++) {
			if (picIndex[i] == idx) {
				return i;
			}
		}

		return -1;
	}

	private void initTimers() {
		timerThread = new TimerThread();
		timerHandler = new Handler() {
			// @Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				switch (msg.what) {
				case TIME_COUNT:
					// runClock();
					break;
				case AUTO_PLAY:
					autoMoveBlock();
					break;
				case MUSIC_START:
					break;
				}

				super.handleMessage(msg);
			}
		};

		timerThread.start();
	}

	class TimerThread extends Thread {
		// @Override
		public void run() {
			// TODO Auto-generated method stub
			while (true) {
				Message msg = new Message();

				if (isGameStart) {
					msg.what = TIME_COUNT;

					timerHandler.sendMessage(msg);
				}

				if (isAutoPlay) {
					msg.what = AUTO_PLAY;

					timerHandler.sendMessage(msg);
				}

				if (isMusicNeedStart) {
					isMusicNeedStart = false;

					msg.what = MUSIC_START;

					timerHandler.sendMessage(msg);
				}

				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	private void findViews() {
		btn_restore = (Button) findViewById(R.id.btn_restore);
		btn_ruffle = (Button) findViewById(R.id.btn_ruffle);
		btn_demo = (Button) findViewById(R.id.btn_demo);
		btn_setting = (Button) findViewById(R.id.btn_setting);
		btn_select = (Button) findViewById(R.id.btn_select);
		iv_target = (ImageView) findViewById(R.id.img_target);
		tl_puzzle = (TableLayout) findViewById(R.id.tl_blocks_layout);
		btn_restore.setOnClickListener(this);
		btn_ruffle.setOnClickListener(this);
		btn_demo.setOnClickListener(this);
		btn_setting.setOnClickListener(this);
		btn_select.setOnClickListener(this);
		sourcePicture = BitmapFactory.decodeResource(getResources(),
				R.drawable.beauty1);
	}

	private void restorePicBlocks() {

		isGameStart = false;
		initPicIndex();// ��ʼ��ƴͼ����(��picIndex,�����Ǹ�����!)
		showAllPicBlocks();
	}

	private void initPicIndex() {
		picIndex = new int[rows * cols];
		for (int i = 0; i < rows * cols; i++) {
			picIndex[i] = i;
		}
	}

	private void showAllPicBlocks() {
		for (int i = 0; i < picIndex.length; i++) {
			showPicBlock(picIndex[i], i);
		}
	}

	private void showPicBlock(int idx, int blockIdx) {
		ImageView curBlock = (ImageView) findViewById(RES_ID_BASE + blockIdx);

		int row = getRowIndex(idx);
		int col = getColIndex(idx);

		Bitmap bitmap = zoomBitmap(sourcePicture, picWidth, picHeight);
		Bitmap bit = Bitmap.createBitmap(bitmap, col * blockWidth, row
				* blockHeight, blockWidth, blockHeight);
		Bitmap bit_highlight = toGrayscale(bit);

		if (control_type == 0) {
			curBlock.setImageBitmap(bit);
		} else if (control_type == 1) {
			if (idx == rows * cols - 1) {
				curBlock.setImageBitmap(bit_highlight);
			} else {
				curBlock.setImageBitmap(bit);
			}
		}
	}

	public static Bitmap toGrayscale(Bitmap bmpOriginal) {
		int width, height;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();

		Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
				Bitmap.Config.RGB_565);
		Canvas c = new Canvas(bmpGrayscale);
		Paint paint = new Paint();
		ColorMatrix cm = new ColorMatrix();
		// float[] array = { 1f, 0f, 0f, 0f, 100f, 0f, 2f, 0f, 0f, 100f, 0f, 0f,
		// 1f, 0f, 0f, 0f, 0f, 0f, 1f, 0f };//黄色
		float[] array = { 1f, 0f, 0f, 0f, 200f, 0f, 1f, 0f, 0f, 50f, 0f, 0f,
				1f, 0f, 300f, 0f, 0f, 0f, 1f, 0f };// 红色

		cm.set(array);
		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);

		c.drawBitmap(bmpOriginal, 0, 0, paint);

		final Paint paint1 = new Paint();
		final Rect rect = new Rect(0, 0, bmpGrayscale.getWidth(), bmpGrayscale
				.getHeight());

		paint.setAntiAlias(true);
		c.drawARGB(50, 20, 250, 255);

		paint1.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		c.drawBitmap(bmpGrayscale, rect, rect, paint1);
		return bmpGrayscale;

	}

	public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidht = ((float) w / width);
		float scaleHeight = ((float) h / height);
		matrix.postScale(scaleWidht, scaleHeight);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		return newbmp;
	}

	private int getColIndex(int idx) {
		return (idx % cols);
	}

	private int getRowIndex(int idx) {
		return idx / cols;
	}

	private void rufflePicBlocks() {
		isGameStart = false;

		initPicIndex();

		originPicIndex = new int[cols * rows];

		resolveSteps = new ArrayList<Integer>();

		if (initRuffleLevel == 0) {
			game = new JigsawGame(cols);
			game.initProperty();
			game.initResolve();

			while (game.hasResolve == false) {
				game.initProperty();
				game.initResolve();

				game.randomInit();

				game.resolve();
			}

			Log.i("Info", "Original Resolve Steps:" + game.resolveSteps.size());
			game.optimize();
			Log
					.i("Info", "Optimized Resolve Steps:"
							+ game.resolveSteps.size());

			if (game.verify()) {
				Log.i("Info", "Verify resolve steps success!");
			}

			//
			for (int i = 0; i < cols * rows; i++) {
				picIndex[i] = game.originPicIndex[i] - 1;
			}

			//
			for (int i = game.resolveSteps.size() - 1; i >= 0; i--) {
				resolveSteps.add(game.resolveSteps.get(i).intValue() - 1);
			}

		} else {
			for (int i = 0; i < initRuffleLevel; i++) {
				int firstIndex = getBlankLocation();
				int secondIndex = getRandomNextIndex(firstIndex);

				if ((firstIndex != secondIndex)
						&& (secondIndex < picIndex.length)) {

					int intTemp = picIndex[firstIndex];
					picIndex[firstIndex] = picIndex[secondIndex];
					picIndex[secondIndex] = intTemp;

					resolveSteps.add(firstIndex);
				}
			}
		}

		showAllPicBlocks();

		for (int i = 0; i < cols * rows; i++) {
			originPicIndex[i] = picIndex[i];
		}

		ticker = 0;
		isGameStart = true;
	}

	private int getRandomNextIndex(int curIndex) {
		int moveIndex = (int) (Math.random() * 1000) % 4;
		int newIndex = curIndex;
		switch (moveIndex) {
		case 0:
			if ((isBlankCanMoveRight(curIndex))
					&& (lastMoveDirect.equalsIgnoreCase("left") == false)) {
				lastMoveDirect = "right";
				newIndex = curIndex + 1;
			}
			break;
		case 1:
			if ((isBlankCanMoveDown(curIndex))
					&& (lastMoveDirect.equalsIgnoreCase("up") == false)) {
				lastMoveDirect = "down";
				newIndex = curIndex + cols;
			}
			break;
		case 2:
			if ((isBlankCanMoveLeft(curIndex))
					&& (lastMoveDirect.equalsIgnoreCase("right") == false)) {
				lastMoveDirect = "left";
				newIndex = curIndex - 1;
			}
			break;
		case 3:
			if ((isBlankCanMoveUp(curIndex))
					&& (lastMoveDirect.equalsIgnoreCase("down") == false)) {
				lastMoveDirect = "up";
				newIndex = curIndex - cols;
			}
			break;
		default:
			newIndex = curIndex;
			break;
		}

		return newIndex;
	}

	private boolean isBlankCanMoveLeft(int curBlank) {
		if ((curBlank % cols) >= 1) {
			return true;
		} else {
			return false;
		}
	}

	private boolean isBlankCanMoveRight(int curBlank) {
		if ((curBlank % cols) < (cols - 1)) {
			return true;
		} else {
			return false;
		}
	}

	private boolean isBlankCanMoveUp(int curBlank) {
		if (curBlank / cols >= 1) {
			return true;
		} else {
			return false;
		}
	}

	private boolean isBlankCanMoveDown(int curBlank) {
		if (curBlank / cols < (rows - 1)) {
			return true;
		} else {
			return false;
		}
	}

	private void changeGameImage(Bitmap strPic) {
		boolean isSettingChanged = false;
		sourcePicture = strPic;
		isSettingChanged = true;
		if (isSettingChanged) {
			initPicBlocks();
		}
	}

	private void changeGameSettings(int ctrlType, int strRows, int strCols) {
		boolean isSettingChanged = false;
		isSettingChanged = true;

		if (control_type != ctrlType) {
			control_type = ctrlType;
			isSettingChanged = true;
		}

		if (rows != strRows) {
			rows = strRows;
			blockHeight = picHeight / rows;
			isSettingChanged = true;
		}

		if (cols != strCols) {
			cols = strCols;
			blockWidth = picWidth / cols;
			isSettingChanged = true;
		}

		if (isSettingChanged) {
			initPicBlocks();
		}
	}

	private void showSettingView() {
		LayoutInflater factory = LayoutInflater.from(this);
		final View settingView = factory.inflate(R.layout.setting, null);
		RadioGroup rg1 = (RadioGroup) settingView
				.findViewById(R.id.radiogroup_game);
		final RadioButton rb_easy = (RadioButton) settingView
				.findViewById(R.id.radioButton_easy);
		final RadioButton rb_difficult = (RadioButton) settingView
				.findViewById(R.id.radioButton_difficult);
		final RadioButton rb_tricky = (RadioButton) settingView
				.findViewById(R.id.radioButton_tricky);
		RadioGroup rg2 = (RadioGroup) settingView
				.findViewById(R.id.radiogroup_control);
		final RadioButton rb_control_easy = (RadioButton) settingView
				.findViewById(R.id.radioButton_control_easy);
		final RadioButton rb_control_difficult = (RadioButton) settingView
				.findViewById(R.id.radioButton_control_difficult);

		switch (rows) {
		case 3:
			rb_easy.setChecked(true);
			break;
		case 4:
			rb_difficult.setChecked(true);
			break;
		case 5:
			rb_tricky.setChecked(true);
			break;
		default:
			rb_easy.setChecked(true);
			break;
		}

		if (control_type == 0) {
			rb_control_easy.setChecked(true);
		} else {
			rb_control_difficult.setChecked(true);
		}

		rg1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// TODO Auto-generated method stub
				if (checkedId == rb_easy.getId()) {
					temp_row = 3;
					temp_col = 3;
				} else if (checkedId == rb_difficult.getId()) {
					temp_row = 4;
					temp_col = 4;
				} else if (checkedId == rb_tricky.getId()) {
					temp_row = 5;
					temp_col = 5;
				}
			}
		});

		rg2.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// TODO Auto-generated method stub
				if (checkedId == rb_control_easy.getId()) {
					temp_type = 0;
				} else if (checkedId == rb_control_difficult.getId()) {
					temp_type = 1;
				}
			}
		});

		new AlertDialog.Builder(this).setTitle("").setView(settingView)
				.setPositiveButton(getResources().getString(R.string.confirm),
						new DialogInterface.OnClickListener() {

							public void onClick(DialogInterface dialog,
									int which) {
								// TODO Auto-generated method stub
								changeGameSettings(temp_type, temp_row,
										temp_col);
							}
						}).setNegativeButton(
						getResources().getString(R.string.cancel),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog,
									int whichButton) {
								dialog.dismiss();
							}
						}).create().show();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_restore:
			restorePicBlocks();// ��ԭƴͼ
			break;
		case R.id.btn_ruffle:
			rufflePicBlocks();// ����ƴͼ
			break;
		case R.id.btn_demo:
			demoAutoPlay();
			break;
		case R.id.btn_setting:
			showSettingView();
			break;
		case R.id.btn_select:
			Intent intent = new Intent();
			intent.setType("image/*");
			intent.setAction(Intent.ACTION_GET_CONTENT);
			startActivityForResult(intent, 1);
			break;
		default:
			break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(1, 1, 1, getResources().getString(R.string.select_image));
		return true;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		// TODO Auto-generated method stub
		if (item.getItemId() == 1) {
			Intent intent = new Intent();
			intent.setType("image/*");
			intent.setAction(Intent.ACTION_GET_CONTENT);
			startActivityForResult(intent, 1);
		}
		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			Uri uri = data.getData();
			ContentResolver cr = this.getContentResolver();
			try {
				Bitmap bitmap = BitmapFactory.decodeStream(cr
						.openInputStream(uri));
				ImageView imageView = (ImageView) findViewById(R.id.img_target);
				imageView.setImageBitmap(bitmap);
				changeGameImage(bitmap);
			} catch (FileNotFoundException e) {
				Log.e("Exception", e.getMessage(), e);
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}
}